<template>
  <div class="waterfall-container" ref="container">
    <!-- 循环渲染列 -->
    <div
        class="waterfall-column"
        v-for="(column, index) in columns"
        :key="index"
        :style="{ width: columnWidth + 'px', marginLeft: index !== 0 ? gutterWidth + 'px' : '0' }"
        ref="columns"
    >
      <!-- 循环渲染列中的图片项 -->
      <div
          class="waterfall-item"
          v-for="(item, itemIndex) in column"
          :key="itemIndex"
          :style="{ height: item.height + 'px', marginBottom: item.marginBottom + 'px' }"
      >
        <!-- 图片加载 -->
        <img
            class="image"
            :src="item.src"
            :alt="item.alt"
            @load="handleImageLoad(index, itemIndex)"
            @click="previewImage(item.src)"
            @mouseover="handleMouseOver"
            @mouseleave="handleMouseLeave"
        />
      </div>
    </div>
  </div>
  <el-image-viewer v-if="imgViewerVisible" :onClose="closeViewer"  :url-list="this.urlList" />

</template>

<script>
import request from "@/util/request.js";

export default {
  data() {
    return {
      items: [], // 存放瀑布流中的数据项
      columns: [], // 存放每一列的数据
      columnCount: 4, // 列数
      columnWidth: 0, // 列宽度
      containerWidth: 0, // 容器的宽度
      gutterWidth: 5, // 图片间隔
      startIndex: 0, // 起始加载图片的索引
      loadCount: 20, // 每次加载的图片数量
      isScrolling: false, // 是否正在滚动
      scrollSpeed: 2, // 滚动速度，值越大滚动越快
      allPhoto:[], // 后端传过来的图片数据
      imgViewerVisible:false,
      urlList:[]
    };
  },
  mounted() {
    this.containerWidth = this.$refs.container.clientWidth;
    this.columnWidth = (this.containerWidth - (this.columnCount - 1) * this.gutterWidth) / this.columnCount;
    this.getAddPhoto();
  },
  methods: {
    // 获取全部照片
    getAddPhoto(){
      request.get("/related_photo/allPhoto").then(res=>{
        this.allPhoto.push(...res.data.data)
        this.initItems();
        this.autoScroll();
      })
    },
    // 初始化瀑布流数据项
    initItems() {
      const imagePaths = this.allPhoto;

      // 生成图片数据，以达到无限循环的效果
      while (this.items.length < 100) {
        this.items.push(...this.shuffle(imagePaths));
      }

      // 初始化列数据
      for (let i = 0; i < this.columnCount; i++) {
        this.columns.push([]);
      }

      // 加载第一屏的图片
      this.loadImages();
    },
    // 加载图片
    loadImages() {
      this.items.slice(this.startIndex, this.startIndex + this.loadCount).forEach((item, index) => {
        const img = new Image();
        img.src = item.src;
        img.alt = item.alt;
        img.onload = () => {
          const height = (this.columnWidth / img.width) * img.height;
          const itemData = { src: item.src, alt: img.alt, height, marginBottom: this.gutterWidth };
          const columnIndex = this.getMinColumnIndex();
          this.columns[columnIndex].push(itemData);
        };
      });
      // 循环播放图片
      this.startIndex = (this.startIndex + this.loadCount) % this.items.length;
    },
    // 获取当前高度最小的列的索引
    getMinColumnIndex() {
      let minHeight = this.columns[0].reduce((acc, cur) => acc + cur.height + cur.marginBottom, 0);
      let index = 0;
      for (let i = 1; i < this.columns.length; i++) {
        const columnHeight = this.columns[i].reduce((acc, cur) => acc + cur.height + cur.marginBottom, 0);
        if (columnHeight < minHeight) {
          minHeight = columnHeight;
          index = i;
        }
      }
      return index;
    },
    // 图片加载完成后更新布局
    handleImageLoad(columnIndex, itemIndex) {
      this.$nextTick(() => {
        const columnHeight = this.$refs.columns[columnIndex].children[itemIndex].children[0].height;
        const marginBottom = this.gutterWidth;
        this.columns[columnIndex][itemIndex].marginBottom = marginBottom;
      });
    },
    // 图片随机排序
    shuffle(array) {
      for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
      }
      return array;
    },
    // 自动滚动
    autoScroll() {
      const container = this.$refs.container;
      const loadTrigger = container.clientHeight / 3; // 触发加载的阈值设为容器高度的三分之一
      let lastTimestamp = performance.now();
      const scroll = (timestamp) => {
        const deltaTime = timestamp - lastTimestamp;
        container.scrollTop += this.scrollSpeed * deltaTime / 16; // 16ms为一帧的时间
        const currentScrollTop = container.scrollTop;
        const remainingScroll = container.scrollHeight - container.clientHeight - currentScrollTop;
        if (remainingScroll < loadTrigger && !this.isScrolling) { // 判断是否接近底部并且未在加载中
          this.isScrolling = true;
          setTimeout(() => {
            this.loadImages();
            this.isScrolling = false;
          }, 0); // 加载图片前等待一段时间
        }
        lastTimestamp = timestamp;
        requestAnimationFrame(scroll);
      };
      requestAnimationFrame(scroll);
    },
    // 图片预览
    previewImage(src) {
      // 这里可以根据你的需求实现图片预览功能，比如弹出模态框等
      this.urlList.push(src)
      this.imgViewerVisible=true
    },
    closeViewer(){
      if (this.imgViewerVisible){
        this.imgViewerVisible=false
        this.urlList.pop();
      }
    },
    // 鼠标悬停处理
    handleMouseOver(event) {
      event.target.style.transform = 'scale(1.1)'; // 放大图片
      event.target.style.border = '1px solid #000'; // 添加黑色边框
      event.target.style.cursor = 'zoom-in'; // 鼠标指针更换为放大图标
    },
    // 鼠标离开处理
    handleMouseLeave(event) {
      event.target.style.transform = 'scale(1)'; // 恢复原始大小
      event.target.style.border = 'none'; // 移除边框
      event.target.style.cursor = 'default'; // 恢复默认鼠标指针
    },
  }
};
</script>

<style scoped>
.waterfall-container {
  flex-wrap: wrap;
  overflow-y: hidden; /* 隐藏滚动条 */
  height: 100vh;
  width: 100vw;
  display: flex;
  justify-content: center;
  align-items: center;
}

.waterfall-column {
  display: inline-block;
  vertical-align: top;
}

.waterfall-item {
  width: 100%;
  box-sizing: border-box;
}

.image {
  width: 100%;
  height: auto;
  object-fit: cover;
  transition: transform 0.3s; /* 添加过渡效果 */
}
</style>
